package com.cgc.venus.server.job.service;

import com.cgc.venus.server.core.base.AbstractBaseService;
import com.cgc.venus.server.core.bean.response.VenusResponseStatus;
import com.cgc.venus.server.core.exception.VenusException;
import com.cgc.venus.server.core.utils.StringUtil;
import com.cgc.venus.server.job.inter.JobService;
import com.cgc.venus.server.job.jobdetail.BaseJob;
import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class JobServiceImpl extends AbstractBaseService implements JobService{
    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 创建任务
     * @param jobName
     * @param jobClassName
     * @param jobGroupName
     * @param cronExpression
     * @param desc
     * @throws VenusException
     */
    @Override
    public void addJob(String jobName, String jobClassName, String jobGroupName, String cronExpression, String desc) throws VenusException {
        try {
            // 启动调度器
            scheduler.start();
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobName, jobGroupName).withDescription(desc).build();
            //表达式调度构建器(即任务执行的时间)
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                    .withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }

    /**
     * 暂停任务
     * @param jobName
     * @param jobGroupName
     * @throws VenusException
     */
    @Override
    public void pauseJob(String jobName, String jobGroupName) throws VenusException {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
        } catch (SchedulerException e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }

    /**
     * 重启任务
     * @param jobName
     * @param jobGroupName
     * @throws VenusException
     */
    @Override
    public void resumeJob(String jobName, String jobGroupName) throws VenusException {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
        } catch (SchedulerException e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }

    /**
     * 重新设置任务
     * @param jobName
     * @param jobGroupName
     * @param cronExpression
     * @throws VenusException
     */
    @Override
    public void rescheduleJob(String jobName, String jobGroupName, String cronExpression,String desc) throws VenusException {
        try {
            //走更新
            String sql = "update qrtz_job_details set DESCRIPTION=? where JOB_NAME=? and JOB_GROUP=?";
            List<Object> objs = new ArrayList<Object>();
            objs.add(desc);
            objs.add(jobName);
            objs.add(jobGroupName);
            this.jdbcTemplate.update(sql,objs.toArray());

            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }

    /**
     * 删除任务
     * @param jobName
     * @param jobGroupName
     * @throws VenusException
     */
    @Override
    public void deleteJob(String jobName, String jobGroupName) throws VenusException {
        try {
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
        } catch (SchedulerException e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }

    /**
     * 查询任务
     * @param queryKey
     * @return
     * @throws VenusException
     */
    @Override
    public List queryJob(String queryKey,String status) throws VenusException {
        try {
            String sql="SELECT job.JOB_NAME jobName, job.JOB_GROUP jobGroup, job.JOB_CLASS_NAME jobClassName, qct.CRON_EXPRESSION jobCropExpression, qct.TIME_ZONE_ID timeZone, qt.TRIGGER_STATE jobStatus, job.DESCRIPTION jobDesc FROM qrtz_job_details job JOIN qrtz_triggers qt JOIN qrtz_cron_triggers qct ON job.JOB_NAME = qt.JOB_NAME AND qt.TRIGGER_NAME = qct.TRIGGER_NAME AND qt.TRIGGER_GROUP = qct.TRIGGER_GROUP WHERE CONCAT( job.JOB_NAME, job.JOB_GROUP, job.JOB_CLASS_NAME, qct.TIME_ZONE_ID, IFNULL(job.DESCRIPTION, '')) LIKE ?";
            if(StringUtil.isEmpty(queryKey)){
                queryKey="";
            }
            List object=new ArrayList<>();
            object.add("%" +queryKey+"%");
            if(!StringUtil.isEmpty(status)&&!"all".equals(status)){
                sql+=" and qt.TRIGGER_STATE=?";
                object.add(status);
            }
            return jdbcTemplate.queryForList(sql,object.toArray());
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }


    @Override
    public Boolean checkExistsJobKey(String name,String group) throws VenusException {
        try {
            return scheduler.checkExists(new JobKey(name,group));
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,e.getMessage());
        }
    }

    @Override
    public Boolean checkExistsClass(String className) throws VenusException {
        Class<?> class1 = null;
        try {
            class1 = Class.forName(className);
            BaseJob baseJob =(BaseJob)class1.newInstance();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public Boolean checkExistsCornExpression(String cronExpression) throws VenusException {
        CronTriggerImpl trigger = new CronTriggerImpl();
        try {
            trigger.setCronExpression(cronExpression);
            Date date = trigger.computeFirstFireTime(null);
            return date != null && date.after(new Date());
        } catch (Exception e) {
            return false;
        }
    }

    private BaseJob getClass(String classname) throws VenusException {
        Class<?> class1 = null;
        try {
            class1 = Class.forName(classname);
            BaseJob baseJob =(BaseJob)class1.newInstance();
            return baseJob;
        } catch (Exception e) {
            throw new VenusException(VenusResponseStatus.JOB_EXCEPTION,"类格式异常!");
        }
    }


}
